﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using EPiServer;
using EPiServer.Core;
using EPiServer.DataAccess;
using EPiServer.Security;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PageTypeBuilder;
using TemplateFoundation.Configuration;
using TemplateFoundation.Core;
using TemplateFoundation.Core.ContentStructure;
using TemplateFoundation.Tests.Environment;
using TemplateFoundation.Tests.PageTypes;

namespace TemplateFoundation.Tests.UnitTests.Core.ContentStructure
{
    [TestClass]
    public class DateFolderStructureTest
    {
        [TestMethod]
        public void TestUnpublishedPageIsMovedToYearDateFolderWhenAllSettingsAreSpecified()
        {
            var target = PageStructure.CreateStandardPages("Date Folder Root", PageReference.RootPage, 1)[0];

            DataFactory.Instance.Save(target, SaveAction.Publish, AccessLevel.NoAccess);

            // Create page to organize in date folder
            var page = DataFactory.Instance.GetDefaultPageData(
                PageReference.RootPage,
                PageTypeResolver.Instance.GetPageTypeID(typeof (StandardPage)).Value);

            Assert.IsTrue(page.ParentLink==PageReference.RootPage);

            new DateFolderStructure(target.PageLink, 
                                    true,
                                    true,
                                    PageTypeResolver.Instance.GetPageTypeID(typeof (ContainerPage)).Value,
                                    "PageStartPublish",
                                    true,
                                    true,
                                    true).PutInDateFolder(page);

            Assert.AreNotEqual(PageReference.RootPage, page.ParentLink, "Page parent link is still set to Root");

            try
            {
                Assert.AreEqual(PageTypeResolver.Instance.GetPageTypeID(typeof(ContainerPage)).Value, page.ParentLink.GetPage().PageTypeID, "Parent page wasn't of correct date folder type");
            }
            catch (Exception ex)
            {
                Assert.Fail(ex.Message);
            }
            
            Assert.AreEqual(target.PageLink.ID,page.ParentLink.GetPage().ParentLink.ID, "Date folder wasn't located under the specified target");
            Assert.AreEqual(page.StartPublish.Year.ToString(),page.ParentLink.GetPage().PageName, "Parent page wasn't a page named after the correct year");
        }

        [TestMethod]
        public void TestPublishedPageIsMovedToYearDateFolderWhenAllSettingsAreSpecified()
        {
            var target = PageStructure.CreateStandardPages("Date Folder Root", PageReference.RootPage, 1)[0];

            DataFactory.Instance.Save(target, SaveAction.Publish, AccessLevel.NoAccess);

            // Create page to organize in date folder
            var page = PageStructure.CreateStandardPages("Page to Organize in Date Folder", PageReference.RootPage,1)[0];

            Assert.IsTrue(page.ParentLink==PageReference.RootPage);

            new DateFolderStructure(target.PageLink,
                                    true,
                                    true,
                                    PageTypeResolver.Instance.GetPageTypeID(typeof(ContainerPage)).Value,
                                    "PageStartPublish",
                                    true,
                                    true,
                                    true).PutInDateFolder(page);

            page = DataFactory.Instance.GetPage(page.PageLink);

            Assert.AreNotEqual(PageReference.RootPage,page.ParentLink, "Page parent link is still set to Root");

            try
            {
                Assert.AreEqual(PageTypeResolver.Instance.GetPageTypeID(typeof(ContainerPage)).Value, page.ParentLink.GetPage().PageTypeID, "Parent page wasn't of correct date folder type");
            }
            catch (Exception ex)
            {
                Assert.Fail(ex.Message);
            }
            
            Assert.AreEqual(target.PageLink.ID, page.ParentLink.GetPage().ParentLink.ID, "Date folder wasn't located under the specified target");
            Assert.AreEqual(page.StartPublish.Year.ToString(), page.ParentLink.GetPage().PageName, "Parent page wasn't a page named after the correct year");
        }

        [TestMethod]
        public void TestUnpublishedPageIsMovedToMonthDateFolderWhenAllSettingsAreSpecified()
        {
            var target = PageStructure.CreateStandardPages("Date Folder Root", PageReference.RootPage, 1)[0];

            DataFactory.Instance.Save(target, SaveAction.Publish, AccessLevel.NoAccess);

            // Create page to organize in date folder
            var page = DataFactory.Instance.GetDefaultPageData(
                PageReference.RootPage,
                PageTypeResolver.Instance.GetPageTypeID(typeof(StandardPage)).Value);

            Assert.IsTrue(page.ParentLink==PageReference.RootPage);

            new DateFolderStructure(target.PageLink,
                                    false,
                                    true,
                                    PageTypeResolver.Instance.GetPageTypeID(typeof(ContainerPage)).Value,
                                    "PageStartPublish",
                                    true,
                                    true,
                                    true).PutInDateFolder(page);

            Assert.AreNotEqual(PageReference.RootPage,page.ParentLink, "Page parent link is still set to Root");

            try
            {
                Assert.AreEqual(PageTypeResolver.Instance.GetPageTypeID(typeof(ContainerPage)).Value, page.ParentLink.GetPage().PageTypeID, "Parent page wasn't of correct date folder type");
            }
            catch (Exception ex)
            {
                Assert.Fail(ex.Message);
            }
            
            Assert.AreEqual(target.PageLink.ID, page.ParentLink.GetPage().ParentLink.GetPage().ParentLink.ID, "Date folder wasn't located under the specified target");
            Assert.AreEqual(page.StartPublish.Year.ToString(), page.ParentLink.GetPage().ParentLink.GetPage().PageName, "Parent page wasn't a page named after the correct year");
            Assert.AreEqual(page.StartPublish.Month.ToString(), page.ParentLink.GetPage().PageName, "Parent page wasn't a page named after the correct month");
        }

        [TestMethod]
        public void TestPublishedPageIsMovedToMonthDateFolderWhenAllSettingsAreSpecified()
        {
            var target = PageStructure.CreateStandardPages("Date Folder Root", PageReference.RootPage, 1)[0];

            DataFactory.Instance.Save(target, SaveAction.Publish, AccessLevel.NoAccess);

            // Create page to organize in date folder
            var page = PageStructure.CreateStandardPages("Page to Organize in Date Folder", PageReference.RootPage, 1)[0];

            Assert.IsTrue(page.ParentLink==PageReference.RootPage);

            new DateFolderStructure(target.PageLink,
                                    false,
                                    true,
                                    PageTypeResolver.Instance.GetPageTypeID(typeof(ContainerPage)).Value,
                                    "PageStartPublish",
                                    true,
                                    true,
                                    true).PutInDateFolder(page);

            page = DataFactory.Instance.GetPage(page.PageLink);

            Assert.AreNotEqual(PageReference.RootPage, page.ParentLink, "Page parent link is still set to Root");

            try
            {
                Assert.AreEqual(PageTypeResolver.Instance.GetPageTypeID(typeof(ContainerPage)).Value, page.ParentLink.GetPage().PageTypeID, "Parent page wasn't of correct date folder type");
            }
            catch (Exception ex)
            {
                Assert.Fail(ex.Message);
            }
            
            Assert.AreEqual(target.PageLink.ID, page.ParentLink.GetPage().ParentLink.GetPage().ParentLink.ID, "Date folder wasn't located under the specified target");
            Assert.AreEqual(page.StartPublish.Year.ToString(), page.ParentLink.GetPage().ParentLink.GetPage().PageName, "Parent page wasn't a page named after the correct year");
            Assert.AreEqual(page.StartPublish.Month.ToString(), page.ParentLink.GetPage().PageName, "Parent page wasn't a page named after the correct month");
        }

        [TestMethod]
        public void TestVisibleInMenuSettingsWhenSetToTrueForDateFolders()
        {
            var target = PageStructure.CreateStandardPages("Date Folder Root", PageReference.RootPage, 1)[0];

            DataFactory.Instance.Save(target, SaveAction.Publish, AccessLevel.NoAccess);

            // Create page to organize in date folder
            var page = PageStructure.CreateStandardPages("Page to Organize in Date Folder", PageReference.RootPage, 1)[0];

            new DateFolderStructure(target.PageLink,
                                    false,
                                    false,
                                    PageTypeResolver.Instance.GetPageTypeID(typeof(ContainerPage)).Value,
                                    "PageStartPublish",
                                    true,
                                    true,
                                    true).PutInDateFolder(page);

            page = DataFactory.Instance.GetPage(page.PageLink);

            Assert.IsTrue(page.ParentLink.GetPage().ParentLink.GetPage().ParentLink.GetPage().VisibleInMenu, "'Visible in menu' was false for year folder");
            Assert.IsTrue(page.ParentLink.GetPage().ParentLink.GetPage().VisibleInMenu, "'Visible in menu' was false for month folder");
            Assert.IsTrue(page.ParentLink.GetPage().VisibleInMenu, "'Visible in menu' was false for day folder");
        }

        [TestMethod]
        public void TestVisibleInMenuSettingsWhenSetToFalseForDateFolders()
        {
            var target = PageStructure.CreateStandardPages("Date Folder Root", PageReference.RootPage, 1)[0];

            DataFactory.Instance.Save(target, SaveAction.Publish, AccessLevel.NoAccess);

            // Create page to organize in date folder
            var page = PageStructure.CreateStandardPages("Page to Organize in Date Folder", PageReference.RootPage, 1)[0];

            new DateFolderStructure(target.PageLink,
                                    false,
                                    false,
                                    PageTypeResolver.Instance.GetPageTypeID(typeof(ContainerPage)).Value,
                                    "PageStartPublish",
                                    false,
                                    false,
                                    false).PutInDateFolder(page);

            page = DataFactory.Instance.GetPage(page.PageLink);

            Assert.IsFalse(page.ParentLink.GetPage().ParentLink.GetPage().ParentLink.GetPage().VisibleInMenu, "'Visible in menu' was true for year folder");
            Assert.IsFalse(page.ParentLink.GetPage().ParentLink.GetPage().VisibleInMenu, "'Visible in menu' was true for month folder");
            Assert.IsFalse(page.ParentLink.GetPage().VisibleInMenu, "'Visible in menu' was true for day folder");
        }
    }
}
